package main

import (
	"fmt"
	"strings"
	"time"

	"github.com/danbai225/WeChatFerry-go/wcf"
	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

const refreshInterval = 500 * time.Millisecond

var (
	view *tview.Modal
	app  *tview.Application
)

func formatMessage(sender string, content string) string {
	t := time.Now()
	timeStr := t.Format("2006-01-02 15:04:05.000")
	return fmt.Sprintf("%v [%v] - %v", timeStr, sender, content)
}

func handleMesasge(client *wcf.Client, msg *wcf.WxMsg) string {
	supportTypes := []uint32{1, 3, 34, 47, 66, 9999, 10000, 10002, 822083633, 922746929}
	isSupport := false
	for _, v := range supportTypes {
		if v == msg.Type {
			isSupport = true
			break
		}
	}
	if !isSupport {
		return "Unkown Message"
	}
	var sender string
	if msg.IsGroup {
		groupName := client.GetContactInfo(msg.Roomid).Name
		senderInfo := client.GetContactInfo(msg.Sender)
		if len(senderInfo.Remark) != 0 {
			sender = groupName + "->" + senderInfo.Remark
		} else {
			sender = groupName + "->" + senderInfo.Name
		}
	} else {
		senderInfo := client.GetContactInfo(msg.Sender)
		if len(senderInfo.Remark) != 0 {
			sender = senderInfo.Remark
		} else {
			sender = senderInfo.Name
		}
	}
	return formatMessage(sender, msg.Content)
}

func sendMessage(client *wcf.Client, wxid string, msg string) {
	client.SendTxt(msg, wxid, nil)
}

func addMessageToView(app *tview.Application, tv *tview.TextArea, newMsg string) {
	oldText := tv.GetText()
	if len(oldText) == 0 {
		go app.QueueUpdateDraw(func() {
			tv.SetText(newMsg, true)
		})
	} else {
		go app.QueueUpdateDraw(func() {
			tv.SetText(oldText+"\r\n"+newMsg, true)
		})
	}
}
func startMsgRecv(client *wcf.Client, app *tview.Application, tv *tview.TextArea) {
	client.EnableRecvTxt()
	for {
		// 继续执行任务
		time.Sleep(500 * time.Millisecond)
		client.OnMSG(func(msg *wcf.WxMsg) {
			if exclusive {
				if msg.IsGroup && msg.Roomid != targetWxId {
					return
				}
				if !msg.IsGroup && msg.Sender != targetWxId {
					return
				}
			}

			addMessageToView(app, tv, handleMesasge(client, msg))
		})
	}
}

func refreshDraw(app *tview.Application) {
	for {
		time.Sleep(300 * time.Microsecond)
		app.Draw()
	}
}

var targetWxId string
var targetName string
var exclusive bool
var underRecv bool

func main() {
	underRecv = false

	c, err := wcf.NewWCF("")
	if err != nil {
		panic(err)
	}
	if !c.IsLogin() {
		fmt.Println("微信没有登录")
	}

	app := tview.NewApplication()

	histories := tview.NewTextArea()
	histories.SetTitle("ttfish-go").SetBorder(true).SetBorderColor(tcell.NewRGBColor(103, 106, 110))
	histories.SetDisabled(true)

	msg := tview.NewInputField()
	msg.SetBackgroundColor(tcell.ColorBlack)

	mainView := tview.NewGrid().SetRows(0, 1).
		AddItem(histories, 0, 0, 1, 2, 0, 0, true).
		AddItem(msg, 1, 0, 1, 2, 0, 0, true)

	pages := tview.NewPages()

	contactNames_all := []string{}
	contactWxId_all := []string{}

	contactNames := []string{}
	contactWxIds := []string{}

	for _, v := range c.GetContacts() {
		if len(v.Remark) == 0 {
			contactNames_all = append(contactNames_all, v.Name)
			contactNames = append(contactNames, v.Name)
		} else {
			contactNames_all = append(contactNames_all, v.Remark)
			contactNames = append(contactNames, v.Remark)
		}

		contactWxId_all = append(contactWxId_all, v.Wxid)
		contactWxIds = append(contactWxIds, v.Wxid)
	}

	dropDown := tview.NewDropDown().SetLabel("聊天")
	checkBox := tview.NewCheckbox().SetLabel("是否只监听该聊天").SetChecked(false)

	ChatForm := tview.NewForm().
		AddFormItem(tview.NewInputField().SetLabel("搜索").SetFieldWidth(20).SetChangedFunc(func(text string) {
			contactNames = []string{}
			contactWxIds = []string{}
			for i, v := range contactNames_all {
				if strings.Contains(v, text) {
					contactNames = append(contactNames, v)
					contactWxIds = append(contactWxIds, contactWxId_all[i])
				}
			}
			dropDown.SetOptions(contactNames, nil)
		})).
		AddFormItem(dropDown).
		AddFormItem(checkBox).
		AddButton("确定", func() {
			// 选定wxid和name,启动接收
			idx, name := dropDown.GetCurrentOption()
			targetName = name
			targetWxId = contactWxIds[idx]
			exclusive = checkBox.IsChecked()
			pages.HidePage("modal")
			pages.ShowPage("main")

			time.Sleep(500 * time.Millisecond)

			if !underRecv {
				go startMsgRecv(c, app, histories)
				underRecv = true
			}
			msg.SetDoneFunc(func(key tcell.Key) {
				if tcell.KeyEnter == key {
					if "q" == msg.GetText() {
						app.Stop()
						return
					}

					myMsg := msg.GetText()

					addMessageToView(app, histories, formatMessage(c.GetUserInfo().Name+"->"+targetName, myMsg))
					sendMessage(c, targetWxId, myMsg)
					msg.SetText("")
				}
			})
		}).
		AddButton("退出", func() {
			app.Stop()
		})

	modal := func(p tview.Primitive, width, height int) tview.Primitive {
		return tview.NewFlex().
			AddItem(nil, 0, 1, false).
			AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
				AddItem(nil, 0, 1, false).
				AddItem(p, height, 1, true).
				AddItem(nil, 0, 1, false), width, 1, true).
			AddItem(nil, 0, 1, false)
	}

	pages.AddAndSwitchToPage("form", ChatForm, true).AddPage("main", mainView, true, false).AddPage("modal", modal(ChatForm, 40, 10), true, false)

	app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		if event.Key() == tcell.KeyF2 {
			pages.ShowPage("modal") //TODO: Check when clicking outside help window with the mouse. Then clicking help again.
			return nil
		}
		return event
	})

	if err := app.SetRoot(pages, true).EnableMouse(true).Run(); err != nil {
		panic(err)
	}
	c.DisableRecvTxt()
	c.Close()
}
